﻿using System.Windows.Forms;
using AMatysiak.Methods;
using System;

namespace AMatysiak.Controls
{
    public class ValueBox<T> : TextBox
    {
        public ValueBox()
            : base()
        {
            FormatMethodToStrHandler = delegate(T value) { return value.ToString(); };
            FormatMethodToObjHandler = delegate(string value) { return (T)Convert.ChangeType(value, typeof(T)); };

            this.TextChanged += new System.EventHandler(textChanged);
            this.TextAlign = HorizontalAlignment.Right;
            this.LostFocus += delegate { formatText(); };
        }

        private bool interrupt = false;

        public delegate T FormatMethodToObj(string value);
        public FormatMethodToObj FormatMethodToObjHandler;

        private void textChanged(object sender, System.EventArgs e)
        {
            if (interrupt)
                return;

            try
            {
                interrupt = true;
                this.Value = FormatMethodToObjHandler(this.Text);
                interrupt = false;
            }
            catch { }
        }

        public delegate string FormatMethodToStr(T value);
        public FormatMethodToStr FormatMethodToStrHandler;

        private void formatText()
        {
            this.Text = FormatMethodToStrHandler(this.value);
        }

        public delegate void ChangedValueEventArgs(T oldValue, T newValue);
        public event ChangedValueEventArgs ChangedValue;

        private T value;
        public T Value
        {
            get { return value; }
            set
            {
                T old = this.value;

                this.value = value;

                if (!this.Focused)
                    formatText();

                if (ChangedValue != null)
                    ChangedValue(old, value);
            }
        }
    }
}
